import {useEffect, useRef, useState} from "react";
import {filter} from "lodash/collection";
import moment from 'moment';
import _ from 'lodash';
import useEquityHistory from './hooks/useEquityHistory'

function update(chart, data){
}

const comment = props => {
    return <div>点击买入，卖出计算收益率</div>
}
const periods = ["1d", "1w", "1M"];
let currentOverlay = null;
let startTimestamp = null;
let buyPrice = null;
const Tools = (props) => {
    const [started, setStarted] = useState(false);
    const [period, setPeriod] = useState("1d");
    const [stopIndex, setStopIndex] = useState(0);
    const stopIndexRef = useRef(0);
    const aiStartedRef = useRef(false);
    const [data, setData] = useState([]);
    const [dailyData, setDailyData] = useState([]);
    const [weeklyData, setWeeklyData] = useState([]);
    const [monthlyData, setMonthlyData] = useState([]);
    const [canbuy, setCanBuy] = useState(true);
    const [aiStarted, setAIStarted] = useState(false);
    const overlays = [];
    
    // 添加买入卖出标记
    const addTradeMarker = (candle, type, price = null) => {
        if (!props.chart?.current || !candle) return null
        try {
            const tradePrice = price !== null ? price : candle.close
            const label = type === 'buy' 
                ? `买入\n${tradePrice.toFixed(2)}` 
                : `卖出\n${tradePrice.toFixed(2)}`
            const markerId = props.chart.current.createOverlay({
                name: 'simpleAnnotation',
                extendData: label,
                points: [{ timestamp: candle.timestamp, value: type === 'buy' ? candle.low : candle.high }],
                styles: {
                    annotation: {
                        text: {
                            color: type === 'buy' ? '#0dd697' : '#f44336',
                            backgroundColor: type === 'buy' ? 'rgba(13,214,151,0.2)' : 'rgba(244,67,54,0.2)',
                            borderColor: type === 'buy' ? '#0dd697' : '#f44336',
                            textAlign: 'center'
                        }
                    }
                }
            })
            return markerId
        } catch (e) {
            console.warn('Failed to create trade marker:', e)
            return null
        }
    }
    const { history: equityHistory, record: recordEquity, reset: resetEquity } = useEquityHistory(props.trader);
    
    // 将 equityHistory 传递给父组件
    useEffect(() => {
        if (props.onEquityHistoryChange) {
            props.onEquityHistoryChange(equityHistory)
        }
    }, [equityHistory])
    const getTimestampFromData = (arr) => {
        if (!arr || arr.length === 0) {
            return Date.now();
        }
        const last = arr[arr.length - 1];
        if (last && last.volume === 0 && arr.length > 1) {
            const prev = arr[arr.length - 2];
            return prev?.timestamp ?? last.timestamp ?? Date.now();
        }
        return last.timestamp ?? Date.now();
    };
    const recordFromData = (arr) => {
        const ts = getTimestampFromData(arr ?? dailyData);
        recordEquity(ts);
    };
    useEffect(() => {
        if(props.chart && props.chart.current) {
            props.chart.current.resize();
        }
        if(started){
            if(props.hideStrategyInfo){
                props.hideStrategyInfo();
            }
        }
    }, [started]);
    useEffect(() => {
        stopIndexRef.current = stopIndex;
    }, [stopIndex]);

    useEffect(() => {
        aiStartedRef.current = aiStarted;
    }, [aiStarted]);
    useEffect(() => {
        if(started){
            var dt;
            // console.log(period)
            if(period == "1d"){
                props.chart.current.applyNewData(dailyData);
                dt = dailyData;
            } else if(period == "1w"){
                // console.log(weeklyData)
                props.chart.current.applyNewData(weeklyData);
                dt = weeklyData;
            } else if(period == "1M"){
                props.chart.current.applyNewData(monthlyData);
                dt = monthlyData;
            }

            for(var indicatorStrategy of props.indicatorStrategies){
                if(indicatorStrategy.reset){
                    indicatorStrategy.reset(props.chart.current);
                }
                indicatorStrategy.update(props.chart.current, dt);
            }
            if (props.onDataApplied && dt && dt.length) {
                props.onDataApplied(dt);
            }
        }
    }, [period]);
    const getLongPeriodData = function(dailyData){
        var weeklyData = [];
        var monthlyData = [];
        for(const line of dailyData){
            var time = moment.unix(line.time / 1000);
            var startOfWeek = time.clone().startOf('isoWeek').unix() * 1000;
            var startOfMonth = time.clone().startOf('month').unix() * 1000;

            if(weeklyData.length == 0 || weeklyData[weeklyData.length-1].timestamp != startOfWeek) {
                weeklyData.push({
                    open: line.open,
                    close: line.close,
                    high: line.high,
                    low: line.low,
                    timestamp: startOfWeek,
                    volume: line.volume,
                    amount: line.amount
                })
            }
            weeklyData[weeklyData.length-1].close = line.close;
            weeklyData[weeklyData.length-1].high = Math.max(weeklyData[weeklyData.length-1].high, line.high);
            weeklyData[weeklyData.length-1].low = Math.min(weeklyData[weeklyData.length-1].low, line.low);
            weeklyData[weeklyData.length-1].volume += line.volume;
            weeklyData[weeklyData.length-1].amount += line.amount;

            if(monthlyData.length == 0 || monthlyData[monthlyData.length-1].timestamp != startOfMonth) {
                monthlyData.push({
                    open: line.open,
                    close: line.close,
                    high: line.high,
                    low: line.low,
                    timestamp: startOfMonth,
                    volume: line.volume,
                    amount: line.amount
                })
            }
            monthlyData[monthlyData.length-1].close = line.close;
            monthlyData[monthlyData.length-1].high = Math.max(monthlyData[monthlyData.length-1].high, line.high);
            monthlyData[monthlyData.length-1].low = Math.min(monthlyData[monthlyData.length-1].low, line.low);
            monthlyData[monthlyData.length-1].volume += line.volume;
            monthlyData[monthlyData.length-1].amount += line.amount;

        }
        setWeeklyData(weeklyData);
        setMonthlyData(monthlyData);
        // console.log(weeklyData, monthlyData)

    }

    const onAIResponse = async (imageBase64) => {
        const response = await fetch("http://192.168.2.65:8787/vision-decision", {
            method: "POST",
            headers: {"Content-Type": "application/json"},
            body: JSON.stringify({
                image_base64: imageBase64.replace(/^data:image\/png;base64,/, ""),
                prompt: `你是一位专业的股票技术分析AI，请根据图中的K线、布林带、成交量、KDJ指标和TD序列等综合因素，判断当前时点最合理的操作建议，仅从以下三者中选择并回答一个，不要有空格：
[buy]、[sell]、[hold]
当前仓位：${canbuy ? "空仓" : "持仓"}
${!canbuy ? "买入时价格：" + buyPrice : ""}
持仓只可以卖出或持有，空仓只可以买入或持有。
分析顺序请依次判断：
1. K线当前结构是否呈现趋势信号（如放量突破、连续阳线或阴线、强支撑或压力位）；  
2. 是否形成布林带开口扩张或缩口收敛，是否出轨并回归，或触及上轨/下轨方向明确；  
3. KDJ指标是否形成明显金叉/死叉，是否高位钝化或低位发散；  
4. TD计数是否达到关键点（如TD9出现或TD买卖反转）；  
5. 成交量是否有效放大或缩量滞涨/滞跌，是否形成量价背离；
6. 买入时构成的角度是否大于45度，卖出时构成的角度是否小于-45度；
7. 参考买入时价格和当前价格，是否利益最大化，如果已经利益最大化，卖出
8. 要考虑常见的顶部形态和底部形态，如头肩顶、头肩底、双顶、双底、圆弧顶、圆弧底、底分型、顶分型、倾盆大雨、乌云盖顶等；
9. 参考图中辅助线（如趋势线、支撑线、压力线等）是否形成有效突破或反转信号；
10. 所有都要参考最后一根K线做出决策；
11. 当出现底部大阳线优先考虑卖入，除非有其他风险
12. 当出现顶部大阴线优先考虑卖出，不考虑其他机会

如果当前市场结构趋势明确（例如趋势延续、反转信号清晰），请选择【买入】或【卖出】；  
若信号模糊、震荡无主、指标矛盾，请选择【持有】。

请你最终只输出以下三个字之一并紧跟简单说明，不要有空格：
[buy]、[sell]、[hold]
简单说明：示例文字
`
            })
        });
        const data = await response.json();
        const decision = JSON.stringify(data);
        console.log("AI decision", decision)
        if (decision.includes("[buy]") && canbuy) {
            buy();
        } else if (decision.includes("[sell]") && !canbuy) {
            sell();
        } else {
            hold();
        }
    };

    const next = function () {
        var minval = _.min(data.map(c => c.low));

        const index = Math.min(stopIndexRef.current + 1, data.length - 1);
        setStopIndex(index);
        stopIndexRef.current = index; // 同步 ref 值

        if (period !== "1d") {
            setPeriod("1d");
        }

        var displayData = data.slice(0, index);
        displayData.push({
            open: displayData[displayData.length - 1].close,
            close: displayData[displayData.length - 1].close,
            high: displayData[displayData.length - 1].close,
            low: displayData[displayData.length - 1].close,
            volume: 0,
            amount: 0,
            timestamp: displayData[displayData.length - 1].timestamp + 24 * 60 * 60 * 1000
        });

        setDailyData(displayData);

        if (startTimestamp) {
            var color = buyPrice < displayData[displayData.length - 1].close ? "rgba(255,22,22,0.15)" : "rgba(13,190,28,0.15)";
            if (currentOverlay) {
                props.chart.current.removeOverlay(currentOverlay);
            }
            currentOverlay = props.chart.current.createOverlay({
                name: 'rect',
                styles: {
                    polygon: {
                        color
                    }
                },
                points: [
                    { timestamp: startTimestamp, value: _.max(data.map(c => c.high)) },
                    { timestamp: displayData[displayData.length - 1].timestamp, value: minval }
                ]
            });
        }

        getLongPeriodData(displayData);
        props.chart.current.applyNewData(displayData);

        for (var indicatorStrategy of props.indicatorStrategies) {
            if (indicatorStrategy.reset) {
                indicatorStrategy.reset(props.chart.current);
            }
            indicatorStrategy.update(props.chart.current, displayData);
        }
        if (props.onDataApplied && displayData && displayData.length) {
            props.onDataApplied(displayData);
        }
        recordFromData(displayData);

        props.setPrice(displayData[displayData.length - 1].close);

        console.log("aiStarted", aiStartedRef.current); // ✅ 用 ref 保证准确

        if (aiStartedRef.current) {
            const chartImage = props.chart.current.getConvertPictureUrl(true, "png", "#000000");
            //将chartImage显示在屏幕右下角，设id为chartdemo，并删除原来的chartdemo
            const chartdemo = document.getElementById("chartdemo");
            if (chartdemo) {
                chartdemo.remove();
            }
            const img = document.createElement("img");
            img.id = "chartdemo";
            img.src = chartImage;
            img.style.position = "absolute";
            img.style.right = "0px";
            img.style.bottom = "0px";
            img.style.width = "200px";
            img.style.height = "200px";
            img.style.zIndex = "9999";
            img.style.border = "1px solid red";
            img.style.borderRadius = "10px";
            img.style.boxShadow = "0 0 10px rgba(0, 0, 0, 0.5)";
            img.style.pointerEvents = "none";
            img.style.transition = "all 0.5s ease";
            img.style.transform = "scale(0.5)";
            img.style.transformOrigin = "bottom right";
            img.style.opacity = "0.5";
            document.body.appendChild(img);
            console.log("AI request");
            onAIResponse(chartImage).then();
        }
    }
    const stop = function(){
       window.location.reload()
    }

    const buy = function(){
        const candle = dailyData[dailyData.length - 1];
        buyPrice = candle.close;
        props.trader.buy(candle.close)
        startTimestamp = candle.timestamp;
        const buyMarker = addTradeMarker(candle, 'buy', candle.close)
        if (buyMarker) {
            overlays.push(buyMarker)
        }
        next();
        setCanBuy(false)
    }

    const sell = function(){
        const candle = dailyData[dailyData.length - 1];
        props.trader.sell(candle.close)
        startTimestamp = null;
        const sellMarker = addTradeMarker(candle, 'sell', candle.close)
        if (sellMarker) {
            overlays.push(sellMarker)
        }
        if(currentOverlay){
            overlays.push(currentOverlay)
        }
        currentOverlay = null;
        next();
        setCanBuy(true)
    }

    const hold = function(){
        props.trader.hold(dailyData[dailyData.length - 1].close)
        next();
        console.log("hold next")

    }
    useEffect(() => {
        if (aiStarted) {
            hold(); // 此时一定是更新之后了
        }
    }, [aiStarted]);
    const onAIClicked = function(){
        if(!aiStarted){
            console.log("turn on AI")
            setAIStarted(true);
        } else {
            console.log("turn off AI")
            setAIStarted(false);
        }
    }
    return (
        <div style={{display: 'flex', flexDirection: 'column', gap: 12}}>
            {started && <div className={"periods"} style={{display:'flex'}}>
                {periods.map(c => <div key={c} className={"period"} style={{marginRight: 10, cursor: "pointer", color: c === period ? "red" : "white"}} onClick={() => { setPeriod(c) }}>{c}</div>)}
            </div>}
            <div style={{display: 'flex', flexDirection: 'row', gap: 12, alignItems: 'center', flexWrap: 'wrap'}}>
                {!started && <button onClick={async () => {
                    var chart = props.chart;
                    var stocks = props.stocks;
                    var filteredStocks = stocks.filter(c=>(c.code.startsWith("60") && c.code.endsWith("SH")) || (c.code.startsWith("00") && c.code.endsWith("SZ")) || (c.code.startsWith("30") && c.code.endsWith("SZ")));
                    // console.log(filteredStocks)
                    filteredStocks = filteredStocks.filter(c=>moment.unix(c.open).year() <= 2010 && c.name.includes("ST") === false);
                var stock = filteredStocks[Math.floor(Math.random()*filteredStocks.length)];
                var dates = props.dates;
                dates = dates.filter(c=>c / 1000 >= stock.open && moment.unix(c / 1000).year() <= 2021);
                var endDate = dates[Math.floor(Math.random()*dates.length)];

                var dailyData = await props.getKlines(stock.code, "1d", endDate, 600);
                // setDailyData(dailyData);
                setData(dailyData);
                var index = Math.floor(dailyData.length / 2);
                setStopIndex(index);
                var displayData = dailyData.slice(0, index);
                if (props.trader?.reset) {
                    props.trader.reset();
                }
                resetEquity();
                setDailyData(displayData);
                getLongPeriodData(displayData);
                displayData.push({
                    open: displayData[displayData.length - 1].close,
                    close: displayData[displayData.length - 1].close,
                    high: displayData[displayData.length - 1].close,
                    low: displayData[displayData.length - 1].close,
                    volume: 0,
                    amount: 0,
                    timestamp: displayData[displayData.length - 1].timestamp + 24 * 60 * 60 * 1000
                })
                props.chart.current.applyNewData(displayData);
                for(var indicatorStrategy of props.indicatorStrategies){
                    if(indicatorStrategy.reset){
                        indicatorStrategy.reset(props.chart.current);
                    }
                    indicatorStrategy.update(props.chart.current, displayData);
                }
                    if (props.onDataApplied && displayData && displayData.length) {
                        props.onDataApplied(displayData);
                    }
                    recordFromData(displayData);
                    setStarted(true)
                    props.setInfoDisplay(false)
                }}>开始</button>}
                {started && <>
                    {canbuy && <button onClick={buy}>买入</button>}
                    <button onClick={hold}>持有</button>
                    {!canbuy && <button onClick={sell}>卖出</button>}
                    <button onClick={stop}>结束</button>
                    <button onClick={onAIClicked}>{!aiStarted ? "AI自动运行" : "停止AI自动运行"}</button>
                </>}
            </div>
        </div>
    );
}

export default {update, name: "游戏", comment, Tools};
